home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / a_utils / yacc / byacc / byacc.lha / test / ftp.tab.c < prev    next >
C/C++ Source or Header  |  1993-02-22  |  40KB  |  1,744 lines

  1. #ifndef lint
  2. static char yysccsid[] = "@(#)yaccpar    1.9 (Berkeley) 02/21/93";
  3. #endif
  4. #define YYBYACC 1
  5. #define YYMAJOR 1
  6. #define YYMINOR 9
  7. #define yyclearin (yychar=(-1))
  8. #define yyerrok (yyerrflag=0)
  9. #define YYRECOVERING (yyerrflag!=0)
  10. #define YYPREFIX "yy"
  11. #line 26 "ftp.y"
  12.  
  13. #ifndef lint
  14. static char sccsid[] = "@(#)ftpcmd.y    5.20.1.1 (Berkeley) 3/2/89";
  15. #endif /* not lint */
  16.  
  17. #include <sys/param.h>
  18. #include <sys/socket.h>
  19.  
  20. #include <netinet/in.h>
  21.  
  22. #include <arpa/ftp.h>
  23.  
  24. #include <stdio.h>
  25. #include <signal.h>
  26. #include <ctype.h>
  27. #include <pwd.h>
  28. #include <setjmp.h>
  29. #include <syslog.h>
  30. #include <sys/stat.h>
  31. #include <time.h>
  32.  
  33. extern    struct sockaddr_in data_dest;
  34. extern    int logged_in;
  35. extern    struct passwd *pw;
  36. extern    int guest;
  37. extern    int logging;
  38. extern    int type;
  39. extern    int form;
  40. extern    int debug;
  41. extern    int timeout;
  42. extern    int maxtimeout;
  43. extern  int pdata;
  44. extern    char hostname[], remotehost[];
  45. extern    char proctitle[];
  46. extern    char *globerr;
  47. extern    int usedefault;
  48. extern  int transflag;
  49. extern  char tmpline[];
  50. char    **glob();
  51.  
  52. static    int cmd_type;
  53. static    int cmd_form;
  54. static    int cmd_bytesz;
  55. char    cbuf[512];
  56. char    *fromname;
  57.  
  58. char    *index();
  59. #line 60 "ftp.tab.c"
  60. #define A 257
  61. #define B 258
  62. #define C 259
  63. #define E 260
  64. #define F 261
  65. #define I 262
  66. #define L 263
  67. #define N 264
  68. #define P 265
  69. #define R 266
  70. #define S 267
  71. #define T 268
  72. #define SP 269
  73. #define CRLF 270
  74. #define COMMA 271
  75. #define STRING 272
  76. #define NUMBER 273
  77. #define USER 274
  78. #define PASS 275
  79. #define ACCT 276
  80. #define REIN 277
  81. #define QUIT 278
  82. #define PORT 279
  83. #define PASV 280
  84. #define TYPE 281
  85. #define STRU 282
  86. #define MODE 283
  87. #define RETR 284
  88. #define STOR 285
  89. #define APPE 286
  90. #define MLFL 287
  91. #define MAIL 288
  92. #define MSND 289
  93. #define MSOM 290
  94. #define MSAM 291
  95. #define MRSQ 292
  96. #define MRCP 293
  97. #define ALLO 294
  98. #define REST 295
  99. #define RNFR 296
  100. #define RNTO 297
  101. #define ABOR 298
  102. #define DELE 299
  103. #define CWD 300
  104. #define LIST 301
  105. #define NLST 302
  106. #define SITE 303
  107. #define STAT 304
  108. #define HELP 305
  109. #define NOOP 306
  110. #define MKD 307
  111. #define RMD 308
  112. #define PWD 309
  113. #define CDUP 310
  114. #define STOU 311
  115. #define SMNT 312
  116. #define SYST 313
  117. #define SIZE 314
  118. #define MDTM 315
  119. #define UMASK 316
  120. #define IDLE 317
  121. #define CHMOD 318
  122. #define LEXERR 319
  123. #define YYERRCODE 256
  124. short yylhs[] = {                                        -1,
  125.     0,    0,    0,    1,    1,    1,    1,    1,    1,    1,
  126.     1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  127.     1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  128.     1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  129.     1,    1,    1,    1,    1,    1,    2,    3,    4,    4,
  130.    12,    5,   13,   13,   13,    6,    6,    6,    6,    6,
  131.     6,    6,    6,    7,    7,    7,    8,    8,    8,   10,
  132.    14,   11,    9,
  133. };
  134. short yylen[] = {                                         2,
  135.     0,    2,    2,    4,    4,    4,    2,    4,    4,    4,
  136.     4,    8,    5,    5,    5,    3,    5,    3,    5,    5,
  137.     2,    5,    4,    2,    3,    5,    2,    4,    2,    5,
  138.     5,    3,    3,    4,    6,    5,    7,    9,    4,    6,
  139.     5,    2,    5,    5,    2,    2,    5,    1,    0,    1,
  140.     1,   11,    1,    1,    1,    1,    3,    1,    3,    1,
  141.     1,    3,    2,    1,    1,    1,    1,    1,    1,    1,
  142.     1,    1,    0,
  143. };
  144. short yydefred[] = {                                      1,
  145.     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  146.    73,   73,   73,    0,   73,    0,    0,   73,   73,   73,
  147.    73,    0,    0,    0,    0,   73,   73,   73,   73,   73,
  148.     0,   73,   73,    2,    3,   46,    0,    0,   45,    0,
  149.     7,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  150.    24,    0,    0,    0,    0,    0,   21,    0,    0,   27,
  151.    29,    0,    0,    0,    0,    0,   42,    0,    0,   48,
  152.     0,   50,    0,    0,    0,    0,    0,   60,    0,    0,
  153.    64,   66,   65,    0,   68,   69,   67,    0,    0,    0,
  154.     0,    0,    0,   71,    0,   70,    0,    0,   25,    0,
  155.    18,    0,   16,    0,   73,    0,   73,    0,    0,    0,
  156.     0,   32,   33,    0,    0,    0,    4,    5,    0,    6,
  157.     0,    0,    0,   51,   63,    8,    9,   10,    0,    0,
  158.     0,    0,   11,    0,   23,    0,    0,    0,    0,    0,
  159.    34,    0,    0,   39,    0,    0,   28,    0,    0,    0,
  160.     0,    0,    0,   55,   53,   54,   57,   59,   62,   13,
  161.    14,   15,    0,   47,   22,   26,   19,   17,    0,    0,
  162.    36,    0,    0,   20,   30,   31,   41,   43,   44,    0,
  163.     0,   35,   72,    0,   40,    0,    0,    0,   37,    0,
  164.     0,   12,    0,    0,   38,    0,    0,    0,   52,
  165. };
  166. short yydgoto[] = {                                       1,
  167.    34,   35,   71,   73,   75,   80,   84,   88,   45,   95,
  168.   184,  125,  157,   96,
  169. };
  170. short yysindex[] = {                                      0,
  171.  -224, -247, -239, -236, -232, -222, -204, -200, -181, -177,
  172.     0,    0,    0, -166,    0, -161, -199,    0,    0,    0,
  173.     0, -160, -159, -264, -158,    0,    0,    0,    0,    0,
  174.  -157,    0,    0,    0,    0,    0, -167, -162,    0, -156,
  175.     0, -250, -198, -165, -155, -154, -153, -151, -150, -152,
  176.     0, -145, -252, -229, -217, -302,    0, -144, -146,    0,
  177.     0, -142, -141, -140, -139, -137,    0, -136, -135,    0,
  178.  -134,    0, -133, -132, -130, -131, -128,    0, -249, -127,
  179.     0,    0,    0, -126,    0,    0,    0, -125, -152, -152,
  180.  -152, -205, -152,    0, -124,    0, -152, -152,    0, -152,
  181.     0, -143,    0, -173,    0, -171,    0, -152, -123, -152,
  182.  -152,    0,    0, -152, -152, -152,    0,    0, -138,    0,
  183.  -164, -164, -122,    0,    0,    0,    0,    0, -121, -120,
  184.  -118, -148,    0, -117,    0, -116, -115, -114, -113, -112,
  185.     0, -163, -111,    0, -110, -109,    0, -107, -106, -105,
  186.  -104, -103, -129,    0,    0,    0,    0,    0,    0,    0,
  187.     0,    0, -101,    0,    0,    0,    0,    0, -100, -102,
  188.     0,  -98, -102,    0,    0,    0,    0,    0,    0,  -99,
  189.   -97,    0,    0,  -95,    0,  -96,  -94,  -92,    0, -152,
  190.   -93,    0,  -91,  -90,    0,  -88,  -87,  -86,    0,
  191. };
  192. short yyrindex[] = {                                      0,
  193.     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  194.     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  195.     0,    0,  -83,    0,    0,    0,    0,    0,    0,    0,
  196.     0,    0,    0,    0,    0,    0,    0,  -82,    0,    0,
  197.     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  198.     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  199.     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  200.     0,    0,    0,    0,    0,  -81,  -80,    0, -158,    0,
  201.     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  202.     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  203.     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  204.     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  205.     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  206.     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  207.     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  208.     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  209.     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  210.     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  211.     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  212.     0,    0,    0,    0,    0,    0,    0,    0,    0,
  213. };
  214. short yygindex[] = {                                      0,
  215.     0,    0,    0,    0,    0,    0,    0,    0,   16,  -89,
  216.   -25,   35,   47,    0,
  217. };
  218. #define YYTABLESIZE 190
  219. short yytable[] = {                                     129,
  220.   130,  131,  104,  134,   59,   60,   76,  136,  137,   77,
  221.   138,   78,   79,  105,  106,  107,   98,   99,  146,  123,
  222.   148,  149,   36,  124,  150,  151,  152,   46,   47,   37,
  223.    49,    2,   38,   52,   53,   54,   55,   39,   58,  100,
  224.   101,   62,   63,   64,   65,   66,   40,   68,   69,    3,
  225.     4,  102,  103,    5,    6,    7,    8,    9,   10,   11,
  226.    12,   13,   81,  132,  133,   41,   82,   83,   42,   14,
  227.    51,   15,   16,   17,   18,   19,   20,   21,   22,   23,
  228.    24,   25,   26,   27,   28,   29,   30,   43,   31,   32,
  229.    33,   44,   85,   86,  154,  140,  141,  143,  144,  155,
  230.   193,   87,   48,  156,   70,  170,  171,   50,   56,   72,
  231.    57,   61,   67,   89,   90,   91,   74,  163,   93,   94,
  232.   142,   92,  145,   97,  108,  109,  110,  111,  139,  112,
  233.   113,  114,  115,  116,  153,  117,  118,  121,  119,  120,
  234.   122,  180,  126,  127,  128,  135,  147,  186,  160,  161,
  235.   124,  162,  164,  165,  166,  167,  168,  159,  173,  169,
  236.   174,  172,  175,  176,  177,  178,  179,  181,  158,  182,
  237.   183,  185,  190,  187,  189,  188,  191,  192,  195,  194,
  238.   196,    0,    0,  198,  197,   73,  199,   49,   56,   58,
  239. };
  240. short yycheck[] = {                                      89,
  241.    90,   91,  305,   93,  269,  270,  257,   97,   98,  260,
  242.   100,  262,  263,  316,  317,  318,  269,  270,  108,  269,
  243.   110,  111,  270,  273,  114,  115,  116,   12,   13,  269,
  244.    15,  256,  269,   18,   19,   20,   21,  270,   23,  269,
  245.   270,   26,   27,   28,   29,   30,  269,   32,   33,  274,
  246.   275,  269,  270,  278,  279,  280,  281,  282,  283,  284,
  247.   285,  286,  261,  269,  270,  270,  265,  266,  269,  294,
  248.   270,  296,  297,  298,  299,  300,  301,  302,  303,  304,
  249.   305,  306,  307,  308,  309,  310,  311,  269,  313,  314,
  250.   315,  269,  258,  259,  259,  269,  270,  269,  270,  264,
  251.   190,  267,  269,  268,  272,  269,  270,  269,  269,  272,
  252.   270,  270,  270,  269,  269,  269,  273,  266,  269,  272,
  253.   105,  273,  107,  269,  269,  272,  269,  269,  272,  270,
  254.   270,  269,  269,  269,  273,  270,  270,  269,  271,  270,
  255.   269,  271,  270,  270,  270,  270,  270,  173,  270,  270,
  256.   273,  270,  270,  270,  270,  270,  270,  123,  269,  272,
  257.   270,  273,  270,  270,  270,  270,  270,  269,  122,  270,
  258.   273,  270,  269,  273,  270,  273,  271,  270,  270,  273,
  259.   271,   -1,   -1,  271,  273,  269,  273,  270,  270,  270,
  260. };
  261. #define YYFINAL 1
  262. #ifndef YYDEBUG
  263. #define YYDEBUG 0
  264. #endif
  265. #define YYMAXTOKEN 319
  266. #if YYDEBUG
  267. char *yyname[] = {
  268. "end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  269. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  270. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  271. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  272. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  273. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  274. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"A","B","C","E","F","I","L","N",
  275. "P","R","S","T","SP","CRLF","COMMA","STRING","NUMBER","USER","PASS","ACCT",
  276. "REIN","QUIT","PORT","PASV","TYPE","STRU","MODE","RETR","STOR","APPE","MLFL",
  277. "MAIL","MSND","MSOM","MSAM","MRSQ","MRCP","ALLO","REST","RNFR","RNTO","ABOR",
  278. "DELE","CWD","LIST","NLST","SITE","STAT","HELP","NOOP","MKD","RMD","PWD","CDUP",
  279. "STOU","SMNT","SYST","SIZE","MDTM","UMASK","IDLE","CHMOD","LEXERR",
  280. };
  281. char *yyrule[] = {
  282. "$accept : cmd_list",
  283. "cmd_list :",
  284. "cmd_list : cmd_list cmd",
  285. "cmd_list : cmd_list rcmd",
  286. "cmd : USER SP username CRLF",
  287. "cmd : PASS SP password CRLF",
  288. "cmd : PORT SP host_port CRLF",
  289. "cmd : PASV CRLF",
  290. "cmd : TYPE SP type_code CRLF",
  291. "cmd : STRU SP struct_code CRLF",
  292. "cmd : MODE SP mode_code CRLF",
  293. "cmd : ALLO SP NUMBER CRLF",
  294. "cmd : ALLO SP NUMBER SP R SP NUMBER CRLF",
  295. "cmd : RETR check_login SP pathname CRLF",
  296. "cmd : STOR check_login SP pathname CRLF",
  297. "cmd : APPE check_login SP pathname CRLF",
  298. "cmd : NLST check_login CRLF",
  299. "cmd : NLST check_login SP STRING CRLF",
  300. "cmd : LIST check_login CRLF",
  301. "cmd : LIST check_login SP pathname CRLF",
  302. "cmd : STAT check_login SP pathname CRLF",
  303. "cmd : STAT CRLF",
  304. "cmd : DELE check_login SP pathname CRLF",
  305. "cmd : RNTO SP pathname CRLF",
  306. "cmd : ABOR CRLF",
  307. "cmd : CWD check_login CRLF",
  308. "cmd : CWD check_login SP pathname CRLF",
  309. "cmd : HELP CRLF",
  310. "cmd : HELP SP STRING CRLF",
  311. "cmd : NOOP CRLF",
  312. "cmd : MKD check_login SP pathname CRLF",
  313. "cmd : RMD check_login SP pathname CRLF",
  314. "cmd : PWD check_login CRLF",
  315. "cmd : CDUP check_login CRLF",
  316. "cmd : SITE SP HELP CRLF",
  317. "cmd : SITE SP HELP SP STRING CRLF",
  318. "cmd : SITE SP UMASK check_login CRLF",
  319. "cmd : SITE SP UMASK check_login SP octal_number CRLF",
  320. "cmd : SITE SP CHMOD check_login SP octal_number SP pathname CRLF",
  321. "cmd : SITE SP IDLE CRLF",
  322. "cmd : SITE SP IDLE SP NUMBER CRLF",
  323. "cmd : STOU check_login SP pathname CRLF",
  324. "cmd : SYST CRLF",
  325. "cmd : SIZE check_login SP pathname CRLF",
  326. "cmd : MDTM check_login SP pathname CRLF",
  327. "cmd : QUIT CRLF",
  328. "cmd : error CRLF",
  329. "rcmd : RNFR check_login SP pathname CRLF",
  330. "username : STRING",
  331. "password :",
  332. "password : STRING",
  333. "byte_size : NUMBER",
  334. "host_port : NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER",
  335. "form_code : N",
  336. "form_code : T",
  337. "form_code : C",
  338. "type_code : A",
  339. "type_code : A SP form_code",
  340. "type_code : E",
  341. "type_code : E SP form_code",
  342. "type_code : I",
  343. "type_code : L",
  344. "type_code : L SP byte_size",
  345. "type_code : L byte_size",
  346. "struct_code : F",
  347. "struct_code : R",
  348. "struct_code : P",
  349. "mode_code : S",
  350. "mode_code : B",
  351. "mode_code : C",
  352. "pathname : pathstring",
  353. "pathstring : STRING",
  354. "octal_number : NUMBER",
  355. "check_login :",
  356. };
  357. #endif
  358. #ifndef YYSTYPE
  359. typedef int YYSTYPE;
  360. #endif
  361. #ifdef YYSTACKSIZE
  362. #undef YYMAXDEPTH
  363. #define YYMAXDEPTH YYSTACKSIZE
  364. #else
  365. #ifdef YYMAXDEPTH
  366. #define YYSTACKSIZE YYMAXDEPTH
  367. #else
  368. #define YYSTACKSIZE 500
  369. #define YYMAXDEPTH 500
  370. #endif
  371. #endif
  372. int yydebug;
  373. int yynerrs;
  374. int yyerrflag;
  375. int yychar;
  376. short *yyssp;
  377. YYSTYPE *yyvsp;
  378. YYSTYPE yyval;
  379. YYSTYPE yylval;
  380. short yyss[YYSTACKSIZE];
  381. YYSTYPE yyvs[YYSTACKSIZE];
  382. #define yystacksize YYSTACKSIZE
  383. #line 658 "ftp.y"
  384.  
  385. extern jmp_buf errcatch;
  386.  
  387. #define    CMD    0    /* beginning of command */
  388. #define    ARGS    1    /* expect miscellaneous arguments */
  389. #define    STR1    2    /* expect SP followed by STRING */
  390. #define    STR2    3    /* expect STRING */
  391. #define    OSTR    4    /* optional SP then STRING */
  392. #define    ZSTR1    5    /* SP then optional STRING */
  393. #define    ZSTR2    6    /* optional STRING after SP */
  394. #define    SITECMD    7    /* SITE command */
  395. #define    NSTR    8    /* Number followed by a string */
  396.  
  397. struct tab {
  398.     char    *name;
  399.     short    token;
  400.     short    state;
  401.     short    implemented;    /* 1 if command is implemented */
  402.     char    *help;
  403. };
  404.  
  405. struct tab cmdtab[] = {        /* In order defined in RFC 765 */
  406.     { "USER", USER, STR1, 1,    "<sp> username" },
  407.     { "PASS", PASS, ZSTR1, 1,    "<sp> password" },
  408.     { "ACCT", ACCT, STR1, 0,    "(specify account)" },
  409.     { "SMNT", SMNT, ARGS, 0,    "(structure mount)" },
  410.     { "REIN", REIN, ARGS, 0,    "(reinitialize server state)" },
  411.     { "QUIT", QUIT, ARGS, 1,    "(terminate service)", },
  412.     { "PORT", PORT, ARGS, 1,    "<sp> b0, b1, b2, b3, b4" },
  413.     { "PASV", PASV, ARGS, 1,    "(set server in passive mode)" },
  414.     { "TYPE", TYPE, ARGS, 1,    "<sp> [ A | E | I | L ]" },
  415.     { "STRU", STRU, ARGS, 1,    "(specify file structure)" },
  416.     { "MODE", MODE, ARGS, 1,    "(specify transfer mode)" },
  417.     { "RETR", RETR, STR1, 1,    "<sp> file-name" },
  418.     { "STOR", STOR, STR1, 1,    "<sp> file-name" },
  419.     { "APPE", APPE, STR1, 1,    "<sp> file-name" },
  420.     { "MLFL", MLFL, OSTR, 0,    "(mail file)" },
  421.     { "MAIL", MAIL, OSTR, 0,    "(mail to user)" },
  422.     { "MSND", MSND, OSTR, 0,    "(mail send to terminal)" },
  423.     { "MSOM", MSOM, OSTR, 0,    "(mail send to terminal or mailbox)" },
  424.     { "MSAM", MSAM, OSTR, 0,    "(mail send to terminal and mailbox)" },
  425.     { "MRSQ", MRSQ, OSTR, 0,    "(mail recipient scheme question)" },
  426.     { "MRCP", MRCP, STR1, 0,    "(mail recipient)" },
  427.     { "ALLO", ALLO, ARGS, 1,    "allocate storage (vacuously)" },
  428.     { "REST", REST, ARGS, 0,    "(restart command)" },
  429.     { "RNFR", RNFR, STR1, 1,    "<sp> file-name" },
  430.     { "RNTO", RNTO, STR1, 1,    "<sp> file-name" },
  431.     { "ABOR", ABOR, ARGS, 1,    "(abort operation)" },
  432.     { "DELE", DELE, STR1, 1,    "<sp> file-name" },
  433.     { "CWD",  CWD,  OSTR, 1,    "[ <sp> directory-name ]" },
  434.     { "XCWD", CWD,    OSTR, 1,    "[ <sp> directory-name ]" },
  435.     { "LIST", LIST, OSTR, 1,    "[ <sp> path-name ]" },
  436.     { "NLST", NLST, OSTR, 1,    "[ <sp> path-name ]" },
  437.     { "SITE", SITE, SITECMD, 1,    "site-cmd [ <sp> arguments ]" },
  438.     { "SYST", SYST, ARGS, 1,    "(get type of operating system)" },
  439.     { "STAT", STAT, OSTR, 1,    "[ <sp> path-name ]" },
  440.     { "HELP", HELP, OSTR, 1,    "[ <sp> <string> ]" },
  441.     { "NOOP", NOOP, ARGS, 1,    "" },
  442.     { "MKD",  MKD,  STR1, 1,    "<sp> path-name" },
  443.     { "XMKD", MKD,  STR1, 1,    "<sp> path-name" },
  444.     { "RMD",  RMD,  STR1, 1,    "<sp> path-name" },
  445.     { "XRMD", RMD,  STR1, 1,    "<sp> path-name" },
  446.     { "PWD",  PWD,  ARGS, 1,    "(return current directory)" },
  447.     { "XPWD", PWD,  ARGS, 1,    "(return current directory)" },
  448.     { "CDUP", CDUP, ARGS, 1,    "(change to parent directory)" },
  449.     { "XCUP", CDUP, ARGS, 1,    "(change to parent directory)" },
  450.     { "STOU", STOU, STR1, 1,    "<sp> file-name" },
  451.     { "SIZE", SIZE, OSTR, 1,    "<sp> path-name" },
  452.     { "MDTM", MDTM, OSTR, 1,    "<sp> path-name" },
  453.     { NULL,   0,    0,    0,    0 }
  454. };
  455.  
  456. struct tab sitetab[] = {
  457.     { "UMASK", UMASK, ARGS, 1,    "[ <sp> umask ]" },
  458.     { "IDLE", IDLE, ARGS, 1,    "[ <sp> maximum-idle-time ]" },
  459.     { "CHMOD", CHMOD, NSTR, 1,    "<sp> mode <sp> file-name" },
  460.     { "HELP", HELP, OSTR, 1,    "[ <sp> <string> ]" },
  461.     { NULL,   0,    0,    0,    0 }
  462. };
  463.  
  464. struct tab *
  465. lookup(p, cmd)
  466.     register struct tab *p;
  467.     char *cmd;
  468. {
  469.  
  470.     for (; p->name != NULL; p++)
  471.         if (strcmp(cmd, p->name) == 0)
  472.             return (p);
  473.     return (0);
  474. }
  475.  
  476. #include <arpa/telnet.h>
  477.  
  478. /*
  479.  * getline - a hacked up version of fgets to ignore TELNET escape codes.
  480.  */
  481. char *
  482. getline(s, n, iop)
  483.     char *s;
  484.     register FILE *iop;
  485. {
  486.     register c;
  487.     register char *cs;
  488.  
  489.     cs = s;
  490. /* tmpline may contain saved command from urgent mode interruption */
  491.     for (c = 0; tmpline[c] != '\0' && --n > 0; ++c) {
  492.         *cs++ = tmpline[c];
  493.         if (tmpline[c] == '\n') {
  494.             *cs++ = '\0';
  495.             if (debug)
  496.                 syslog(LOG_DEBUG, "command: %s", s);
  497.             tmpline[0] = '\0';
  498.             return(s);
  499.         }
  500.         if (c == 0)
  501.             tmpline[0] = '\0';
  502.     }
  503.     while ((c = getc(iop)) != EOF) {
  504.         c &= 0377;
  505.         if (c == IAC) {
  506.             if ((c = getc(iop)) != EOF) {
  507.             c &= 0377;
  508.             switch (c) {
  509.             case WILL:
  510.             case WONT:
  511.                 c = getc(iop);
  512.                 printf("%c%c%c", IAC, DONT, 0377&c);
  513.                 (void) fflush(stdout);
  514.                 continue;
  515.             case DO:
  516.             case DONT:
  517.                 c = getc(iop);
  518.                 printf("%c%c%c", IAC, WONT, 0377&c);
  519.                 (void) fflush(stdout);
  520.                 continue;
  521.             case IAC:
  522.                 break;
  523.             default:
  524.                 continue;    /* ignore command */
  525.             }
  526.             }
  527.         }
  528.         *cs++ = c;
  529.         if (--n <= 0 || c == '\n')
  530.             break;
  531.     }
  532.     if (c == EOF && cs == s)
  533.         return (NULL);
  534.     *cs++ = '\0';
  535.     if (debug)
  536.         syslog(LOG_DEBUG, "command: %s", s);
  537.     return (s);
  538. }
  539.  
  540. static int
  541. toolong()
  542. {
  543.     time_t now;
  544.     extern char *ctime();
  545.     extern time_t time();
  546.  
  547.     reply(421,
  548.       "Timeout (%d seconds): closing control connection.", timeout);
  549.     (void) time(&now);
  550.     if (logging) {
  551.         syslog(LOG_INFO,
  552.             "User %s timed out after %d seconds at %s",
  553.             (pw ? pw -> pw_name : "unknown"), timeout, ctime(&now));
  554.     }
  555.     dologout(1);
  556. }
  557.  
  558. yylex()
  559. {
  560.     static int cpos, state;
  561.     register char *cp, *cp2;
  562.     register struct tab *p;
  563.     int n;
  564.     char c, *strpbrk();
  565.     char *copy();
  566.  
  567.     for (;;) {
  568.         switch (state) {
  569.  
  570.         case CMD:
  571.             (void) signal(SIGALRM, toolong);
  572.             (void) alarm((unsigned) timeout);
  573.             if (getline(cbuf, sizeof(cbuf)-1, stdin) == NULL) {
  574.                 reply(221, "You could at least say goodbye.");
  575.                 dologout(0);
  576.             }
  577.             (void) alarm(0);
  578. #ifdef SETPROCTITLE
  579.             if (strncasecmp(cbuf, "PASS", 4) != NULL)
  580.                 setproctitle("%s: %s", proctitle, cbuf);
  581. #endif /* SETPROCTITLE */
  582.             if ((cp = index(cbuf, '\r'))) {
  583.                 *cp++ = '\n';
  584.                 *cp = '\0';
  585.             }
  586.             if ((cp = strpbrk(cbuf, " \n")))
  587.                 cpos = cp - cbuf;
  588.             if (cpos == 0)
  589.                 cpos = 4;
  590.             c = cbuf[cpos];
  591.             cbuf[cpos] = '\0';
  592.             upper(cbuf);
  593.             p = lookup(cmdtab, cbuf);
  594.             cbuf[cpos] = c;
  595.             if (p != 0) {
  596.                 if (p->implemented == 0) {
  597.                     nack(p->name);
  598.                     longjmp(errcatch,0);
  599.                     /* NOTREACHED */
  600.                 }
  601.                 state = p->state;
  602.                 *(char **)&yylval = p->name;
  603.                 return (p->token);
  604.             }
  605.             break;
  606.  
  607.         case SITECMD:
  608.             if (cbuf[cpos] == ' ') {
  609.                 cpos++;
  610.                 return (SP);
  611.             }
  612.             cp = &cbuf[cpos];
  613.             if ((cp2 = strpbrk(cp, " \n")))
  614.                 cpos = cp2 - cbuf;
  615.             c = cbuf[cpos];
  616.             cbuf[cpos] = '\0';
  617.             upper(cp);
  618.             p = lookup(sitetab, cp);
  619.             cbuf[cpos] = c;
  620.             if (p != 0) {
  621.                 if (p->implemented == 0) {
  622.                     state = CMD;
  623.                     nack(p->name);
  624.                     longjmp(errcatch,0);
  625.                     /* NOTREACHED */
  626.                 }
  627.                 state = p->state;
  628.                 *(char **)&yylval = p->name;
  629.                 return (p->token);
  630.             }
  631.             state = CMD;
  632.             break;
  633.  
  634.         case OSTR:
  635.             if (cbuf[cpos] == '\n') {
  636.                 state = CMD;
  637.                 return (CRLF);
  638.             }
  639.             /* FALLTHROUGH */
  640.  
  641.         case STR1:
  642.         case ZSTR1:
  643.         dostr1:
  644.             if (cbuf[cpos] == ' ') {
  645.                 cpos++;
  646.                 state = state == OSTR ? STR2 : ++state;
  647.                 return (SP);
  648.             }
  649.             break;
  650.  
  651.         case ZSTR2:
  652.             if (cbuf[cpos] == '\n') {
  653.                 state = CMD;
  654.                 return (CRLF);
  655.             }
  656.             /* FALLTHROUGH */
  657.  
  658.         case STR2:
  659.             cp = &cbuf[cpos];
  660.             n = strlen(cp);
  661.             cpos += n - 1;
  662.             /*
  663.              * Make sure the string is nonempty and \n terminated.
  664.              */
  665.             if (n > 1 && cbuf[cpos] == '\n') {
  666.                 cbuf[cpos] = '\0';
  667.                 *(char **)&yylval = copy(cp);
  668.                 cbuf[cpos] = '\n';
  669.                 state = ARGS;
  670.                 return (STRING);
  671.             }
  672.             break;
  673.  
  674.         case NSTR:
  675.             if (cbuf[cpos] == ' ') {
  676.                 cpos++;
  677.                 return (SP);
  678.             }
  679.             if (isdigit(cbuf[cpos])) {
  680.                 cp = &cbuf[cpos];
  681.                 while (isdigit(cbuf[++cpos]))
  682.                     ;
  683.                 c = cbuf[cpos];
  684.                 cbuf[cpos] = '\0';
  685.                 yylval = atoi(cp);
  686.                 cbuf[cpos] = c;
  687.                 state = STR1;
  688.                 return (NUMBER);
  689.             }
  690.             state = STR1;
  691.             goto dostr1;
  692.  
  693.         case ARGS:
  694.             if (isdigit(cbuf[cpos])) {
  695.                 cp = &cbuf[cpos];
  696.                 while (isdigit(cbuf[++cpos]))
  697.                     ;
  698.                 c = cbuf[cpos];
  699.                 cbuf[cpos] = '\0';
  700.                 yylval = atoi(cp);
  701.                 cbuf[cpos] = c;
  702.                 return (NUMBER);
  703.             }
  704.             switch (cbuf[cpos++]) {
  705.  
  706.             case '\n':
  707.                 state = CMD;
  708.                 return (CRLF);
  709.  
  710.             case ' ':
  711.                 return (SP);
  712.  
  713.             case ',':
  714.                 return (COMMA);
  715.  
  716.             case 'A':
  717.             case 'a':
  718.                 return (A);
  719.  
  720.             case 'B':
  721.             case 'b':
  722.                 return (B);
  723.  
  724.             case 'C':
  725.             case 'c':
  726.                 return (C);
  727.  
  728.             case 'E':
  729.             case 'e':
  730.                 return (E);
  731.  
  732.             case 'F':
  733.             case 'f':
  734.                 return (F);
  735.  
  736.             case 'I':
  737.             case 'i':
  738.                 return (I);
  739.  
  740.             case 'L':
  741.             case 'l':
  742.                 return (L);
  743.  
  744.             case 'N':
  745.             case 'n':
  746.                 return (N);
  747.  
  748.             case 'P':
  749.             case 'p':
  750.                 return (P);
  751.  
  752.             case 'R':
  753.             case 'r':
  754.                 return (R);
  755.  
  756.             case 'S':
  757.             case 's':
  758.                 return (S);
  759.  
  760.             case 'T':
  761.             case 't':
  762.                 return (T);
  763.  
  764.             }
  765.             break;
  766.  
  767.         default:
  768.             fatal("Unknown state in scanner.");
  769.         }
  770.         yyerror((char *) 0);
  771.         state = CMD;
  772.         longjmp(errcatch,0);
  773.     }
  774. }
  775.  
  776. upper(s)
  777.     register char *s;
  778. {
  779.     while (*s != '\0') {
  780.         if (islower(*s))
  781.             *s = toupper(*s);
  782.         s++;
  783.     }
  784. }
  785.  
  786. char *
  787. copy(s)
  788.     char *s;
  789. {
  790.     char *p;
  791.     extern char *malloc(), *strcpy();
  792.  
  793.     p = malloc((unsigned) strlen(s) + 1);
  794.     if (p == NULL)
  795.         fatal("Ran out of memory.");
  796.     (void) strcpy(p, s);
  797.     return (p);
  798. }
  799.  
  800. help(ctab, s)
  801.     struct tab *ctab;
  802.     char *s;
  803. {
  804.     register struct tab *c;
  805.     register int width, NCMDS;
  806.     char *type;
  807.  
  808.     if (ctab == sitetab)
  809.         type = "SITE ";
  810.     else
  811.         type = "";
  812.     width = 0, NCMDS = 0;
  813.     for (c = ctab; c->name != NULL; c++) {
  814.         int len = strlen(c->name);
  815.  
  816.         if (len > width)
  817.             width = len;
  818.         NCMDS++;
  819.     }
  820.     width = (width + 8) &~ 7;
  821.     if (s == 0) {
  822.         register int i, j, w;
  823.         int columns, lines;
  824.  
  825.         lreply(214, "The following %scommands are recognized %s.",
  826.             type, "(* =>'s unimplemented)");
  827.         columns = 76 / width;
  828.         if (columns == 0)
  829.             columns = 1;
  830.         lines = (NCMDS + columns - 1) / columns;
  831.         for (i = 0; i < lines; i++) {
  832.             printf("   ");
  833.             for (j = 0; j < columns; j++) {
  834.                 c = ctab + j * lines + i;
  835.                 printf("%s%c", c->name,
  836.                     c->implemented ? ' ' : '*');
  837.                 if (c + lines >= &ctab[NCMDS])
  838.                     break;
  839.                 w = strlen(c->name) + 1;
  840.                 while (w < width) {
  841.                     putchar(' ');
  842.                     w++;
  843.                 }
  844.             }
  845.             printf("\r\n");
  846.         }
  847.         (void) fflush(stdout);
  848.         reply(214, "Direct comments to ftp-bugs@%s.", hostname);
  849.         return;
  850.     }
  851.     upper(s);
  852.     c = lookup(ctab, s);
  853.     if (c == (struct tab *)0) {
  854.         reply(502, "Unknown command %s.", s);
  855.         return;
  856.     }
  857.     if (c->implemented)
  858.         reply(214, "Syntax: %s%s %s", type, c->name, c->help);
  859.     else
  860.         reply(214, "%s%-*s\t%s; unimplemented.", type, width,
  861.             c->name, c->help);
  862. }
  863.  
  864. sizecmd(filename)
  865. char *filename;
  866. {
  867.     switch (type) {
  868.     case TYPE_L:
  869.     case TYPE_I: {
  870.         struct stat stbuf;
  871.         if (stat(filename, &stbuf) < 0 ||
  872.             (stbuf.st_mode&S_IFMT) != S_IFREG)
  873.             reply(550, "%s: not a plain file.", filename);
  874.         else
  875.             reply(213, "%lu", stbuf.st_size);
  876.         break;}
  877.     case TYPE_A: {
  878.         FILE *fin;
  879.         register int c, count;
  880.         struct stat stbuf;
  881.         fin = fopen(filename, "r");
  882.         if (fin == NULL) {
  883.             perror_reply(550, filename);
  884.             return;
  885.         }
  886.         if (fstat(fileno(fin), &stbuf) < 0 ||
  887.             (stbuf.st_mode&S_IFMT) != S_IFREG) {
  888.             reply(550, "%s: not a plain file.", filename);
  889.             (void) fclose(fin);
  890.             return;
  891.         }
  892.  
  893.         count = 0;
  894.         while((c=getc(fin)) != EOF) {
  895.             if (c == '\n')    /* will get expanded to \r\n */
  896.                 count++;
  897.             count++;
  898.         }
  899.         (void) fclose(fin);
  900.  
  901.         reply(213, "%ld", count);
  902.         break;}
  903.     default:
  904.         reply(504, "SIZE not implemented for Type %c.", "?AEIL"[type]);
  905.     }
  906. }
  907. #line 908 "ftp.tab.c"
  908. #define YYABORT goto yyabort
  909. #define YYREJECT goto yyabort
  910. #define YYACCEPT goto yyaccept
  911. #define YYERROR goto yyerrlab
  912. int
  913. yyparse()
  914. {
  915.     register int yym, yyn, yystate;
  916. #if YYDEBUG
  917.     register char *yys;
  918.     extern char *getenv();
  919.  
  920.     if (yys = getenv("YYDEBUG"))
  921.     {
  922.         yyn = *yys;
  923.         if (yyn >= '0' && yyn <= '9')
  924.             yydebug = yyn - '0';
  925.     }
  926. #endif
  927.  
  928.     yynerrs = 0;
  929.     yyerrflag = 0;
  930.     yychar = (-1);
  931.  
  932.     yyssp = yyss;
  933.     yyvsp = yyvs;
  934.     *yyssp = yystate = 0;
  935.  
  936. yyloop:
  937.     if (yyn = yydefred[yystate]) goto yyreduce;
  938.     if (yychar < 0)
  939.     {
  940.         if ((yychar = yylex()) < 0) yychar = 0;
  941. #if YYDEBUG
  942.         if (yydebug)
  943.         {
  944.             yys = 0;
  945.             if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
  946.             if (!yys) yys = "illegal-symbol";
  947.             printf("%sdebug: state %d, reading %d (%s)\n",
  948.                     YYPREFIX, yystate, yychar, yys);
  949.         }
  950. #endif
  951.     }
  952.     if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
  953.             yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
  954.     {
  955. #if YYDEBUG
  956.         if (yydebug)
  957.             printf("%sdebug: state %d, shifting to state %d\n",
  958.                     YYPREFIX, yystate, yytable[yyn]);
  959. #endif
  960.         if (yyssp >= yyss + yystacksize - 1)
  961.         {
  962.             goto yyoverflow;
  963.         }
  964.         *++yyssp = yystate = yytable[yyn];
  965.         *++yyvsp = yylval;
  966.         yychar = (-1);
  967.         if (yyerrflag > 0)  --yyerrflag;
  968.         goto yyloop;
  969.     }
  970.     if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
  971.             yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
  972.     {
  973.         yyn = yytable[yyn];
  974.         goto yyreduce;
  975.     }
  976.     if (yyerrflag) goto yyinrecovery;
  977. #ifdef lint
  978.     goto yynewerror;
  979. #endif
  980. yynewerror:
  981.     yyerror("syntax error");
  982. #ifdef lint
  983.     goto yyerrlab;
  984. #endif
  985. yyerrlab:
  986.     ++yynerrs;
  987. yyinrecovery:
  988.     if (yyerrflag < 3)
  989.     {
  990.         yyerrflag = 3;
  991.         for (;;)
  992.         {
  993.             if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&
  994.                     yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
  995.             {
  996. #if YYDEBUG
  997.                 if (yydebug)
  998.                     printf("%sdebug: state %d, error recovery shifting\
  999.  to state %d\n", YYPREFIX, *yyssp, yytable[yyn]);
  1000. #endif
  1001.                 if (yyssp >= yyss + yystacksize - 1)
  1002.                 {
  1003.                     goto yyoverflow;
  1004.                 }
  1005.                 *++yyssp = yystate = yytable[yyn];
  1006.                 *++yyvsp = yylval;
  1007.                 goto yyloop;
  1008.             }
  1009.             else
  1010.             {
  1011. #if YYDEBUG
  1012.                 if (yydebug)
  1013.                     printf("%sdebug: error recovery discarding state %d\n",
  1014.                             YYPREFIX, *yyssp);
  1015. #endif
  1016.                 if (yyssp <= yyss) goto yyabort;
  1017.                 --yyssp;
  1018.                 --yyvsp;
  1019.             }
  1020.         }
  1021.     }
  1022.     else
  1023.     {
  1024.         if (yychar == 0) goto yyabort;
  1025. #if YYDEBUG
  1026.         if (yydebug)
  1027.         {
  1028.             yys = 0;
  1029.             if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
  1030.             if (!yys) yys = "illegal-symbol";
  1031.             printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
  1032.                     YYPREFIX, yystate, yychar, yys);
  1033.         }
  1034. #endif
  1035.         yychar = (-1);
  1036.         goto yyloop;
  1037.     }
  1038. yyreduce:
  1039. #if YYDEBUG
  1040.     if (yydebug)
  1041.         printf("%sdebug: state %d, reducing by rule %d (%s)\n",
  1042.                 YYPREFIX, yystate, yyn, yyrule[yyn]);
  1043. #endif
  1044.     yym = yylen[yyn];
  1045.     yyval = yyvsp[1-yym];
  1046.     switch (yyn)
  1047.     {
  1048. case 2:
  1049. #line 99 "ftp.y"
  1050.  {
  1051.             fromname = (char *) 0;
  1052.         }
  1053. break;
  1054. case 4:
  1055. #line 106 "ftp.y"
  1056.  {
  1057.             user((char *) yyvsp[-1]);
  1058.             free((char *) yyvsp[-1]);
  1059.         }
  1060. break;
  1061. case 5:
  1062. #line 111 "ftp.y"
  1063.  {
  1064.             pass((char *) yyvsp[-1]);
  1065.             free((char *) yyvsp[-1]);
  1066.         }
  1067. break;
  1068. case 6:
  1069. #line 116 "ftp.y"
  1070.  {
  1071.             usedefault = 0;
  1072.             if (pdata >= 0) {
  1073.                 (void) close(pdata);
  1074.                 pdata = -1;
  1075.             }
  1076.             reply(200, "PORT command successful.");
  1077.         }
  1078. break;
  1079. case 7:
  1080. #line 125 "ftp.y"
  1081.  {
  1082.             passive();
  1083.         }
  1084. break;
  1085. case 8:
  1086. #line 129 "ftp.y"
  1087.  {
  1088.             switch (cmd_type) {
  1089.  
  1090.             case TYPE_A:
  1091.                 if (cmd_form == FORM_N) {
  1092.                     reply(200, "Type set to A.");
  1093.                     type = cmd_type;
  1094.                     form = cmd_form;
  1095.                 } else
  1096.                     reply(504, "Form must be N.");
  1097.                 break;
  1098.  
  1099.             case TYPE_E:
  1100.                 reply(504, "Type E not implemented.");
  1101.                 break;
  1102.  
  1103.             case TYPE_I:
  1104.                 reply(200, "Type set to I.");
  1105.                 type = cmd_type;
  1106.                 break;
  1107.  
  1108.             case TYPE_L:
  1109. #if NBBY == 8
  1110.                 if (cmd_bytesz == 8) {
  1111.                     reply(200,
  1112.                         "Type set to L (byte size 8).");
  1113.                     type = cmd_type;
  1114.                 } else
  1115.                     reply(504, "Byte size must be 8.");
  1116. #else /* NBBY == 8 */
  1117.                 UNIMPLEMENTED for NBBY != 8
  1118. #endif /* NBBY == 8 */
  1119.             }
  1120.         }
  1121. break;
  1122. case 9:
  1123. #line 164 "ftp.y"
  1124.  {
  1125.             switch (yyvsp[-1]) {
  1126.  
  1127.             case STRU_F:
  1128.                 reply(200, "STRU F ok.");
  1129.                 break;
  1130.  
  1131.             default:
  1132.                 reply(504, "Unimplemented STRU type.");
  1133.             }
  1134.         }
  1135. break;
  1136. case 10:
  1137. #line 176 "ftp.y"
  1138.  {
  1139.             switch (yyvsp[-1]) {
  1140.  
  1141.             case MODE_S:
  1142.                 reply(200, "MODE S ok.");
  1143.                 break;
  1144.  
  1145.             default:
  1146.                 reply(502, "Unimplemented MODE type.");
  1147.             }
  1148.         }
  1149. break;
  1150. case 11:
  1151. #line 188 "ftp.y"
  1152.  {
  1153.             reply(202, "ALLO command ignored.");
  1154.         }
  1155. break;
  1156. case 12:
  1157. #line 192 "ftp.y"
  1158.  {
  1159.             reply(202, "ALLO command ignored.");
  1160.         }
  1161. break;
  1162. case 13:
  1163. #line 196 "ftp.y"
  1164.  {
  1165.             if (yyvsp[-3] && yyvsp[-1] != NULL)
  1166.                 retrieve((char *) 0, (char *) yyvsp[-1]);
  1167.             if (yyvsp[-1] != NULL)
  1168.                 free((char *) yyvsp[-1]);
  1169.         }
  1170. break;
  1171. case 14:
  1172. #line 203 "ftp.y"
  1173.  {
  1174.             if (yyvsp[-3] && yyvsp[-1] != NULL)
  1175.                 store((char *) yyvsp[-1], "w", 0);
  1176.             if (yyvsp[-1] != NULL)
  1177.                 free((char *) yyvsp[-1]);
  1178.         }
  1179. break;
  1180. case 15:
  1181. #line 210 "ftp.y"
  1182.  {
  1183.             if (yyvsp[-3] && yyvsp[-1] != NULL)
  1184.                 store((char *) yyvsp[-1], "a", 0);
  1185.             if (yyvsp[-1] != NULL)
  1186.                 free((char *) yyvsp[-1]);
  1187.         }
  1188. break;
  1189. case 16:
  1190. #line 217 "ftp.y"
  1191.  {
  1192.             if (yyvsp[-1])
  1193.                 send_file_list(".");
  1194.         }
  1195. break;
  1196. case 17:
  1197. #line 222 "ftp.y"
  1198.  {
  1199.             if (yyvsp[-3] && yyvsp[-1] != NULL) 
  1200.                 send_file_list((char *) yyvsp[-1]);
  1201.             if (yyvsp[-1] != NULL)
  1202.                 free((char *) yyvsp[-1]);
  1203.         }
  1204. break;
  1205. case 18:
  1206. #line 229 "ftp.y"
  1207.  {
  1208.             if (yyvsp[-1])
  1209.                 retrieve("/bin/ls -lgA", "");
  1210.         }
  1211. break;
  1212. case 19:
  1213. #line 234 "ftp.y"
  1214.  {
  1215.             if (yyvsp[-3] && yyvsp[-1] != NULL)
  1216.                 retrieve("/bin/ls -lgA %s", (char *) yyvsp[-1]);
  1217.             if (yyvsp[-1] != NULL)
  1218.                 free((char *) yyvsp[-1]);
  1219.         }
  1220. break;
  1221. case 20:
  1222. #line 241 "ftp.y"
  1223.  {
  1224.             if (yyvsp[-3] && yyvsp[-1] != NULL)
  1225.                 statfilecmd((char *) yyvsp[-1]);
  1226.             if (yyvsp[-1] != NULL)
  1227.                 free((char *) yyvsp[-1]);
  1228.         }
  1229. break;
  1230. case 21:
  1231. #line 248 "ftp.y"
  1232.  {
  1233.             statcmd();
  1234.         }
  1235. break;
  1236. case 22:
  1237. #line 252 "ftp.y"
  1238.  {
  1239.             if (yyvsp[-3] && yyvsp[-1] != NULL)
  1240.                 delete((char *) yyvsp[-1]);
  1241.             if (yyvsp[-1] != NULL)
  1242.                 free((char *) yyvsp[-1]);
  1243.         }
  1244. break;
  1245. case 23:
  1246. #line 259 "ftp.y"
  1247.  {
  1248.             if (fromname) {
  1249.                 renamecmd(fromname, (char *) yyvsp[-1]);
  1250.                 free(fromname);
  1251.                 fromname = (char *) 0;
  1252.             } else {
  1253.                 reply(503, "Bad sequence of commands.");
  1254.             }
  1255.             free((char *) yyvsp[-1]);
  1256.         }
  1257. break;
  1258. case 24:
  1259. #line 270 "ftp.y"
  1260.  {
  1261.             reply(225, "ABOR command successful.");
  1262.         }
  1263. break;
  1264. case 25:
  1265. #line 274 "ftp.y"
  1266.  {
  1267.             if (yyvsp[-1])
  1268.                 cwd(pw->pw_dir);
  1269.         }
  1270. break;
  1271. case 26:
  1272. #line 279 "ftp.y"
  1273.  {
  1274.             if (yyvsp[-3] && yyvsp[-1] != NULL)
  1275.                 cwd((char *) yyvsp[-1]);
  1276.             if (yyvsp[-1] != NULL)
  1277.                 free((char *) yyvsp[-1]);
  1278.         }
  1279. break;
  1280. case 27:
  1281. #line 286 "ftp.y"
  1282.  {
  1283.             help(cmdtab, (char *) 0);
  1284.         }
  1285. break;
  1286. case 28:
  1287. #line 290 "ftp.y"
  1288.  {
  1289.             register char *cp = (char *)yyvsp[-1];
  1290.  
  1291.             if (strncasecmp(cp, "SITE", 4) == 0) {
  1292.                 cp = (char *)yyvsp[-1] + 4;
  1293.                 if (*cp == ' ')
  1294.                     cp++;
  1295.                 if (*cp)
  1296.                     help(sitetab, cp);
  1297.                 else
  1298.                     help(sitetab, (char *) 0);
  1299.             } else
  1300.                 help(cmdtab, (char *) yyvsp[-1]);
  1301.         }
  1302. break;
  1303. case 29:
  1304. #line 305 "ftp.y"
  1305.  {
  1306.             reply(200, "NOOP command successful.");
  1307.         }
  1308. break;
  1309. case 30:
  1310. #line 309 "ftp.y"
  1311.  {
  1312.             if (yyvsp[-3] && yyvsp[-1] != NULL)
  1313.                 makedir((char *) yyvsp[-1]);
  1314.             if (yyvsp[-1] != NULL)
  1315.                 free((char *) yyvsp[-1]);
  1316.         }
  1317. break;
  1318. case 31:
  1319. #line 316 "ftp.y"
  1320.  {
  1321.             if (yyvsp[-3] && yyvsp[-1] != NULL)
  1322.                 removedir((char *) yyvsp[-1]);
  1323.             if (yyvsp[-1] != NULL)
  1324.                 free((char *) yyvsp[-1]);
  1325.         }
  1326. break;
  1327. case 32:
  1328. #line 323 "ftp.y"
  1329.  {
  1330.             if (yyvsp[-1])
  1331.                 pwd();
  1332.         }
  1333. break;
  1334. case 33:
  1335. #line 328 "ftp.y"
  1336.  {
  1337.             if (yyvsp[-1])
  1338.                 cwd("..");
  1339.         }
  1340. break;
  1341. case 34:
  1342. #line 333 "ftp.y"
  1343.  {
  1344.             help(sitetab, (char *) 0);
  1345.         }
  1346. break;
  1347. case 35:
  1348. #line 337 "ftp.y"
  1349.  {
  1350.             help(sitetab, (char *) yyvsp[-1]);
  1351.         }
  1352. break;
  1353. case 36:
  1354. #line 341 "ftp.y"
  1355.  {
  1356.             int oldmask;
  1357.  
  1358.             if (yyvsp[-1]) {
  1359.                 oldmask = umask(0);
  1360.                 (void) umask(oldmask);
  1361.                 reply(200, "Current UMASK is %03o", oldmask);
  1362.             }
  1363.         }
  1364. break;
  1365. case 37:
  1366. #line 351 "ftp.y"
  1367.  {
  1368.             int oldmask;
  1369.  
  1370.             if (yyvsp[-3]) {
  1371.                 if ((yyvsp[-1] == -1) || (yyvsp[-1] > 0777)) {
  1372.                     reply(501, "Bad UMASK value");
  1373.                 } else {
  1374.                     oldmask = umask(yyvsp[-1]);
  1375.                     reply(200,
  1376.                         "UMASK set to %03o (was %03o)",
  1377.                         yyvsp[-1], oldmask);
  1378.                 }
  1379.             }
  1380.         }
  1381. break;
  1382. case 38:
  1383. #line 366 "ftp.y"
  1384.  {
  1385.             if (yyvsp[-5] && (yyvsp[-1] != NULL)) {
  1386.                 if (yyvsp[-3] > 0777)
  1387.                     reply(501,
  1388.                 "CHMOD: Mode value must be between 0 and 0777");
  1389.                 else if (chmod((char *) yyvsp[-1], yyvsp[-3]) < 0)
  1390.                     perror_reply(550, (char *) yyvsp[-1]);
  1391.                 else
  1392.                     reply(200, "CHMOD command successful.");
  1393.             }
  1394.             if (yyvsp[-1] != NULL)
  1395.                 free((char *) yyvsp[-1]);
  1396.         }
  1397. break;
  1398. case 39:
  1399. #line 380 "ftp.y"
  1400.  {
  1401.             reply(200,
  1402.                 "Current IDLE time limit is %d seconds; max %d",
  1403.                 timeout, maxtimeout);
  1404.         }
  1405. break;
  1406. case 40:
  1407. #line 386 "ftp.y"
  1408.  {
  1409.             if (yyvsp[-1] < 30 || yyvsp[-1] > maxtimeout) {
  1410.                 reply(501,
  1411.             "Maximum IDLE time must be between 30 and %d seconds",
  1412.                     maxtimeout);
  1413.             } else {
  1414.                 timeout = yyvsp[-1];
  1415.                 (void) alarm((unsigned) timeout);
  1416.                 reply(200,
  1417.                     "Maximum IDLE time set to %d seconds",
  1418.                     timeout);
  1419.             }
  1420.         }
  1421. break;
  1422. case 41:
  1423. #line 400 "ftp.y"
  1424.  {
  1425.             if (yyvsp[-3] && yyvsp[-1] != NULL)
  1426.                 store((char *) yyvsp[-1], "w", 1);
  1427.             if (yyvsp[-1] != NULL)
  1428.                 free((char *) yyvsp[-1]);
  1429.         }
  1430. break;
  1431. case 42:
  1432. #line 407 "ftp.y"
  1433.  {
  1434. #ifdef unix
  1435. #ifdef BSD
  1436.             reply(215, "UNIX Type: L%d Version: BSD-%d",
  1437.                 NBBY, BSD);
  1438. #else /* BSD */
  1439.             reply(215, "UNIX Type: L%d", NBBY);
  1440. #endif /* BSD */
  1441. #else /* unix */
  1442.             reply(215, "UNKNOWN Type: L%d", NBBY);
  1443. #endif /* unix */
  1444.         }
  1445. break;
  1446. case 43:
  1447. #line 428 "ftp.y"
  1448.  {
  1449.             if (yyvsp[-3] && yyvsp[-1] != NULL)
  1450.                 sizecmd((char *) yyvsp[-1]);
  1451.             if (yyvsp[-1] != NULL)
  1452.                 free((char *) yyvsp[-1]);
  1453.         }
  1454. break;
  1455. case 44:
  1456. #line 445 "ftp.y"
  1457.  {
  1458.             if (yyvsp[-3] && yyvsp[-1] != NULL) {
  1459.                 struct stat stbuf;
  1460.                 if (stat((char *) yyvsp[-1], &stbuf) < 0)
  1461.                     perror_reply(550, "%s", (char *) yyvsp[-1]);
  1462.                 else if ((stbuf.st_mode&S_IFMT) != S_IFREG) {
  1463.                     reply(550, "%s: not a plain file.",
  1464.                         (char *) yyvsp[-1]);
  1465.                 } else {
  1466.                     register struct tm *t;
  1467.                     struct tm *gmtime();
  1468.                     t = gmtime(&stbuf.st_mtime);
  1469.                     reply(213,
  1470.                         "19%02d%02d%02d%02d%02d%02d",
  1471.                         t->tm_year, t->tm_mon+1, t->tm_mday,
  1472.                         t->tm_hour, t->tm_min, t->tm_sec);
  1473.                 }
  1474.             }
  1475.             if (yyvsp[-1] != NULL)
  1476.                 free((char *) yyvsp[-1]);
  1477.         }
  1478. break;
  1479. case 45:
  1480. #line 467 "ftp.y"
  1481.  {
  1482.             reply(221, "Goodbye.");
  1483.             dologout(0);
  1484.         }
  1485. break;
  1486. case 46:
  1487. #line 472 "ftp.y"
  1488.  {
  1489.             yyerrok;
  1490.         }
  1491. break;
  1492. case 47:
  1493. #line 477 "ftp.y"
  1494.  {
  1495.             char *renamefrom();
  1496.  
  1497.             if (yyvsp[-3] && yyvsp[-1]) {
  1498.                 fromname = renamefrom((char *) yyvsp[-1]);
  1499.                 if (fromname == (char *) 0 && yyvsp[-1]) {
  1500.                     free((char *) yyvsp[-1]);
  1501.                 }
  1502.             }
  1503.         }
  1504. break;
  1505. case 49:
  1506. #line 493 "ftp.y"
  1507.  {
  1508.             *(char **)&(yyval) = "";
  1509.         }
  1510. break;
  1511. case 52:
  1512. #line 504 "ftp.y"
  1513.  {
  1514.             register char *a, *p;
  1515.  
  1516.             a = (char *)&data_dest.sin_addr;
  1517.             a[0] = yyvsp[-10]; a[1] = yyvsp[-8]; a[2] = yyvsp[-6]; a[3] = yyvsp[-4];
  1518.             p = (char *)&data_dest.sin_port;
  1519.             p[0] = yyvsp[-2]; p[1] = yyvsp[0];
  1520.             data_dest.sin_family = AF_INET;
  1521.         }
  1522. break;
  1523. case 53:
  1524. #line 516 "ftp.y"
  1525.  {
  1526.         yyval = FORM_N;
  1527.     }
  1528. break;
  1529. case 54:
  1530. #line 520 "ftp.y"
  1531.  {
  1532.         yyval = FORM_T;
  1533.     }
  1534. break;
  1535. case 55:
  1536. #line 524 "ftp.y"
  1537.  {
  1538.         yyval = FORM_C;
  1539.     }
  1540. break;
  1541. case 56:
  1542. #line 530 "ftp.y"
  1543.  {
  1544.         cmd_type = TYPE_A;
  1545.         cmd_form = FORM_N;
  1546.     }
  1547. break;
  1548. case 57:
  1549. #line 535 "ftp.y"
  1550.  {
  1551.         cmd_type = TYPE_A;
  1552.         cmd_form = yyvsp[0];
  1553.     }
  1554. break;
  1555. case 58:
  1556. #line 540 "ftp.y"
  1557.  {
  1558.         cmd_type = TYPE_E;
  1559.         cmd_form = FORM_N;
  1560.     }
  1561. break;
  1562. case 59:
  1563. #line 545 "ftp.y"
  1564.  {
  1565.         cmd_type = TYPE_E;
  1566.         cmd_form = yyvsp[0];
  1567.     }
  1568. break;
  1569. case 60:
  1570. #line 550 "ftp.y"
  1571.  {
  1572.         cmd_type = TYPE_I;
  1573.     }
  1574. break;
  1575. case 61:
  1576. #line 554 "ftp.y"
  1577.  {
  1578.         cmd_type = TYPE_L;
  1579.         cmd_bytesz = NBBY;
  1580.     }
  1581. break;
  1582. case 62:
  1583. #line 559 "ftp.y"
  1584.  {
  1585.         cmd_type = TYPE_L;
  1586.         cmd_bytesz = yyvsp[0];
  1587.     }
  1588. break;
  1589. case 63:
  1590. #line 565 "ftp.y"
  1591.  {
  1592.         cmd_type = TYPE_L;
  1593.         cmd_bytesz = yyvsp[0];
  1594.     }
  1595. break;
  1596. case 64:
  1597. #line 572 "ftp.y"
  1598.  {
  1599.         yyval = STRU_F;
  1600.     }
  1601. break;
  1602. case 65:
  1603. #line 576 "ftp.y"
  1604.  {
  1605.         yyval = STRU_R;
  1606.     }
  1607. break;
  1608. case 66:
  1609. #line 580 "ftp.y"
  1610.  {
  1611.         yyval = STRU_P;
  1612.     }
  1613. break;
  1614. case 67:
  1615. #line 586 "ftp.y"
  1616.  {
  1617.         yyval = MODE_S;
  1618.     }
  1619. break;
  1620. case 68:
  1621. #line 590 "ftp.y"
  1622.  {
  1623.         yyval = MODE_B;
  1624.     }
  1625. break;
  1626. case 69:
  1627. #line 594 "ftp.y"
  1628.  {
  1629.         yyval = MODE_C;
  1630.     }
  1631. break;
  1632. case 70:
  1633. #line 600 "ftp.y"
  1634.  {
  1635.         /*
  1636.          * Problem: this production is used for all pathname
  1637.          * processing, but only gives a 550 error reply.
  1638.          * This is a valid reply in some cases but not in others.
  1639.          */
  1640.         if (logged_in && yyvsp[0] && strncmp((char *) yyvsp[0], "~", 1) == 0) {
  1641.             *(char **)&(yyval) = *glob((char *) yyvsp[0]);
  1642.             if (globerr != NULL) {
  1643.                 reply(550, globerr);
  1644.                 yyval = NULL;
  1645.             }
  1646.             free((char *) yyvsp[0]);
  1647.         } else
  1648.             yyval = yyvsp[0];
  1649.     }
  1650. break;
  1651. case 72:
  1652. #line 622 "ftp.y"
  1653.  {
  1654.         register int ret, dec, multby, digit;
  1655.  
  1656.         /*
  1657.          * Convert a number that was read as decimal number
  1658.          * to what it would be if it had been read as octal.
  1659.          */
  1660.         dec = yyvsp[0];
  1661.         multby = 1;
  1662.         ret = 0;
  1663.         while (dec) {
  1664.             digit = dec%10;
  1665.             if (digit > 7) {
  1666.                 ret = -1;
  1667.                 break;
  1668.             }
  1669.             ret += digit * multby;
  1670.             multby *= 8;
  1671.             dec /= 10;
  1672.         }
  1673.         yyval = ret;
  1674.     }
  1675. break;
  1676. case 73:
  1677. #line 647 "ftp.y"
  1678.  {
  1679.         if (logged_in)
  1680.             yyval = 1;
  1681.         else {
  1682.             reply(530, "Please login with USER and PASS.");
  1683.             yyval = 0;
  1684.         }
  1685.     }
  1686. break;
  1687. #line 1688 "ftp.tab.c"
  1688.     }
  1689.     yyssp -= yym;
  1690.     yystate = *yyssp;
  1691.     yyvsp -= yym;
  1692.     yym = yylhs[yyn];
  1693.     if (yystate == 0 && yym == 0)
  1694.     {
  1695. #if YYDEBUG
  1696.         if (yydebug)
  1697.             printf("%sdebug: after reduction, shifting from state 0 to\
  1698.  state %d\n", YYPREFIX, YYFINAL);
  1699. #endif
  1700.         yystate = YYFINAL;
  1701.         *++yyssp = YYFINAL;
  1702.         *++yyvsp = yyval;
  1703.         if (yychar < 0)
  1704.         {
  1705.             if ((yychar = yylex()) < 0) yychar = 0;
  1706. #if YYDEBUG
  1707.             if (yydebug)
  1708.             {
  1709.                 yys = 0;
  1710.                 if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
  1711.                 if (!yys) yys = "illegal-symbol";
  1712.                 printf("%sdebug: state %d, reading %d (%s)\n",
  1713.                         YYPREFIX, YYFINAL, yychar, yys);
  1714.             }
  1715. #endif
  1716.         }
  1717.         if (yychar == 0) goto yyaccept;
  1718.         goto yyloop;
  1719.     }
  1720.     if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
  1721.             yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
  1722.         yystate = yytable[yyn];
  1723.     else
  1724.         yystate = yydgoto[yym];
  1725. #if YYDEBUG
  1726.     if (yydebug)
  1727.         printf("%sdebug: after reduction, shifting from state %d \
  1728. to state %d\n", YYPREFIX, *yyssp, yystate);
  1729. #endif
  1730.     if (yyssp >= yyss + yystacksize - 1)
  1731.     {
  1732.         goto yyoverflow;
  1733.     }
  1734.     *++yyssp = yystate;
  1735.     *++yyvsp = yyval;
  1736.     goto yyloop;
  1737. yyoverflow:
  1738.     yyerror("yacc stack overflow");
  1739. yyabort:
  1740.     return (1);
  1741. yyaccept:
  1742.     return (0);
  1743. }
  1744.